package com.newfiber.business.controller;

import com.newfiber.business.constant.BusinessConstants;
import com.newfiber.business.domain.PatrolSection;
import com.newfiber.business.domain.PatrolTask;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskBeginRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskFinishRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskGeneratorDraftRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskQueryRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskSaveRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskStaticsRequest;
import com.newfiber.business.domain.request.patrolTask.PatrolTaskUpdateRequest;
import com.newfiber.business.domain.response.patrolTask.PatrolTaskStatusStatistics;
import com.newfiber.business.enums.EPatrolTaskStatus;
import com.newfiber.business.service.IPatrolPlanService;
import com.newfiber.business.service.IPatrolSectionService;
import com.newfiber.business.service.IPatrolTaskService;
import com.newfiber.common.core.exception.ServiceException;
import com.newfiber.common.core.web.controller.BaseController;
import com.newfiber.common.core.web.domain.Result;
import com.newfiber.common.core.web.page.PageResult;
import com.newfiber.common.log.annotation.Log;
import com.newfiber.common.log.enums.BusinessType;
import com.newfiber.common.security.annotation.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 巡查任务Controller
 *
 * @author X.K
 * @date 2023-02-17
 */
@RestController
@RequestMapping("/patrolTask")
@Api(value = "PAT05-巡查任务", tags = "PAT05-巡查任务")
public class PatrolTaskController extends BaseController {

    @Resource
    private IPatrolTaskService patrolTaskService;

    @Resource
    private IPatrolPlanService patrolPlanService;

    @Resource
    private IPatrolSectionService patrolSectionService;

    /**
     * 新增巡查任务
     */
    @PostMapping("add")
    @RequiresPermissions("businessPatrol:patrolTask:add")
    @ApiOperation(value = "新增巡查任务", position = 10)
    @Log(title = "巡查任务", businessType = BusinessType.INSERT)
    public Result<Long> add(@RequestBody PatrolTaskSaveRequest request) {
        return success(patrolTaskService.insert(request));
    }

    /**
     * 开始巡查
     */
    @PostMapping("beginPatrol")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "开始巡查", position = 20)
    @Log(title = "开始巡查", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> beginPatrol(@RequestBody PatrolTaskBeginRequest request) {
        PatrolTask patrolTask = patrolTaskService.selectDetailBrief(request.getTaskId());
        // 是否有进行中的任务
        long processCount = patrolTaskService.countByUser(patrolTask.getTaskUserId(), patrolTask.getPatrolType(), EPatrolTaskStatus.Proceed);
        if (processCount >= 1) {
            throw new ServiceException("已存在执行中的巡查，无法开始");
        }
        // 如果任务能关联到计划，就更新计划表
        if (null != patrolTask.getPlanId()) {
            // 执行中任务数 +1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "+");
        }
        return success(patrolTaskService.beginPatrol(request));
    }

    /**
     * 取消巡查
     */
    @PutMapping("cancelPatrol")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "取消巡查", position = 30)
    @Log(title = "取消巡查", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> cancelPatrol(Long taskId) {
        // 如果任务能关联到计划，就更新计划表
        PatrolTask patrolTask = patrolTaskService.selectDetail(taskId);
        // 判断这个任务是不是进行中的任务并且能关联到计划，如果是的话，对应plan表 执行中任务数 -1
        if (null != patrolTask.getPlanId() && EPatrolTaskStatus.Proceed.getCode().equals(patrolTask.getStatus())) {
            // 执行中任务数 -1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "-");
        }
        return success(patrolTaskService.cancelPatrol(taskId));
    }

    /**
     * 重新巡查
     */
    @PutMapping("restartPatrol")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "重新巡查", position = 30)
    @Log(title = "重新巡查", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> restartPatrol(Long taskId) {
        PatrolTask patrolTask = patrolTaskService.selectDetailBrief(taskId);
        // 如果任务能关联到计划，就更新计划表
        if (null != patrolTask.getPlanId()) {
            // 执行中任务数 +1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "+");
        }
        return success(patrolTaskService.restartPatrol(taskId));
    }

    /**
     * 结束巡查
     */
    @PostMapping("finishPatrol")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "结束巡查", position = 40)
    @Log(title = "结束巡查", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> finishPatrol(@RequestBody PatrolTaskFinishRequest request) {
        PatrolTask patrolTask = patrolTaskService.selectDetailBrief(request.getPatrolTaskId());
        PatrolSection patrolSection = patrolSectionService.selectDetail(patrolTask.getPatrolSectionId());

        // 如果任务能关联到计划，就更新计划表
        if (null != patrolTask.getPlanId()) {
            // 判断这个任务是不是进行中的，如果是的话，对应plan表 执行中任务数 -1
            if (EPatrolTaskStatus.Proceed.getCode().equals(patrolTask.getStatus())) {
                // 执行中任务数 -1
                patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "-");
            }
            // 已结束任务数 +1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_DONE_COUNT, "+");
        }
        return success(patrolTaskService.finishPatrol(request, patrolSection));
    }

    /**
     * 强制提交
     */
    @PutMapping("forceCommit")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "强制提交", position = 50)
    @Log(title = "强制提交", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> forceCommit(@RequestBody PatrolTaskUpdateRequest request) {
        // 如果任务能关联到计划，就更新计划表
        PatrolTask patrolTask = patrolTaskService.selectDetail(Long.valueOf(request.getTaskId()));
        if (null != patrolTask.getPlanId()) {
            // 判断这个任务是不是进行中的，如果是的话，对应plan表 执行中任务数 -1
            if (EPatrolTaskStatus.Proceed.getCode().equals(patrolTask.getStatus())) {
                // 执行中任务数 -1
                patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "-");
            }
            // 已结束任务数 +1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_DONE_COUNT, "+");
        }
        return success(patrolTaskService.forceCommit(patrolTask));
    }

    /**
     * 停止巡查
     */
    @PutMapping("stopPatrol")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "停止巡查", position = 60)
    @Log(title = "停止巡查", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> stopPatrol(Long taskId) {
        // 如果任务能关联到计划，就更新计划表
        PatrolTask patrolTask = patrolTaskService.selectDetail(taskId);
        if (null != patrolTask.getPlanId()) {
            // 判断这个任务是不是进行中的，如果是的话，对应plan表 执行中任务数 -1
            if (EPatrolTaskStatus.Proceed.getCode().equals(patrolTask.getStatus())) {
                // 执行中任务数 -1
                patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "-");
            }
            // 已结束任务数 +1
            patrolPlanService.updateTaskCount(patrolTask.getPlanId(), BusinessConstants.TASK_DONE_COUNT, "+");
        }
        return success(patrolTaskService.stopPatrol(taskId));
    }

    /**
     * 生成巡查任务草稿
     */
    @PutMapping("generatorDraft")
    @RequiresPermissions("businessPatrol:patrolTask:list")
    @ApiOperation(value = "生成巡查任务草稿", position = 70)
    public Result<Object> generatorDraft(@RequestBody PatrolTaskGeneratorDraftRequest request) {
        return success(patrolTaskService.generatorDraft(request));
    }

    /**
     * 修改巡查任务
     */
    @PutMapping("edit")
    @RequiresPermissions("businessPatrol:patrolTask:edit")
    @ApiOperation(value = "修改巡查任务", position = 80)
    @Log(title = "巡查任务", businessType = BusinessType.UPDATE)
    public Result<Object> edit(@RequestBody PatrolTaskUpdateRequest request) {
        return success(patrolTaskService.update(request));
    }

    /**
     * 删除巡查任务
     */
    @DeleteMapping("/{ids}")
    @RequiresPermissions("businessPatrol:patrolTask:remove")
    @ApiOperation(value = "删除巡查任务", notes = "传入ids(,隔开)", position = 90)
    @Log(title = "巡查任务", businessType = BusinessType.DELETE)
    public Result<Object> remove(@PathVariable String ids) {
        return success(patrolTaskService.delete(ids));
    }

    /**
     * 详细查询巡查任务
     */
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "详细查询巡查任务", position = 100)
    public Result<PatrolTask> detail(@PathVariable("id") Long id) {
        return success(patrolTaskService.selectDetail(id));
    }

    /**
     * 分页查询巡查任务
     */
    @GetMapping("/page")
    @RequiresPermissions("businessPatrol:patrolTask:page")
    @ApiOperation(value = "分页查询巡查任务", position = 100)
    public PageResult<List<PatrolTask>> page(PatrolTaskQueryRequest request) {
        startPage();
        List<PatrolTask> list = patrolTaskService.selectPage(request);
        return pageResult(list);
    }

    /**
     * 列表查询巡查任务
     */
    @GetMapping("/list")
    @RequiresPermissions("businessPatrol:patrolTask:list")
    @ApiOperation(value = "列表查询巡查任务", position = 110)
    public Result<List<PatrolTask>> list(PatrolTaskQueryRequest request) {
        List<PatrolTask> list = patrolTaskService.selectList(request);
        return success(list);
    }

    /**
     * 状态统计
     */
    @GetMapping("/status_statistics")
    @RequiresPermissions("businessPatrol:patrolTask:list")
    @ApiOperation(value = "状态统计", position = 120)
    public Result<List<PatrolTaskStatusStatistics>> list(PatrolTaskStaticsRequest request) {
        List<PatrolTaskStatusStatistics> list = patrolTaskService.statusStatistics(request);
        return success(list);
    }

    /**
     * 根据巡查计划创建巡查任务之后，系统将提前一天通知相关的巡查人员。
     * date: 2023/3/6 下午 03:50
     *
     * @author: LuFan
     * @since JDK 1.8
     */
    @GetMapping("queryTodoTasks")
    @ApiOperation(value = "提前一天通知相关的巡查人员", position = 130)
    public Result queryTodoTasks() {
        patrolTaskService.queryAndNoticeTodoTasks();
        return success(Boolean.TRUE.toString());
    }

    /**
     * 检测超时的任务
     *（到了计划结束的时间还没有开始的，刷新状态和超时时间，发送提醒短信通知相关的巡查人员。
     * date: 2023/3/6 下午 03:50
     *
     * @author: LuFan
     * @since JDK 1.8
     */
    @GetMapping("findExpiredTasks")
    @ApiOperation(value = "检测超时的任务", position = 140)
    public Result findExpiredTasks() {
        patrolTaskService.findExpiredTasks();
        return success(Boolean.TRUE.toString());
    }

    /**
     * 定时提交目前没有提交的巡查任务
     * 每天00点00分00秒提交目前正在进行的并且计划当前时间之前结束的任务以及任务对应的日志
     * date: 2023/3/6 下午 03:50
     *
     * @author: LuFan
     * @since JDK 1.8
     */
    @GetMapping("autoCommitTask")
    @ApiOperation(value = "定时提交目前没有提交的巡查任务", position = 150)
    public Result autoCommitTask() {
        PatrolTaskQueryRequest request = new PatrolTaskQueryRequest();
        request.setStatus(EPatrolTaskStatus.Proceed.getCode());
        request.setTaskPlanEndDateTo(new Date());
        List<PatrolTask> patrolTasks = patrolTaskService.selectList(request);
        patrolTasks.forEach(e -> {
            patrolTaskService.forceCommit(e);
            // 执行中任务数 -1
            patrolPlanService.updateTaskCount(e.getPlanId(), BusinessConstants.TASK_PROCEED_COUNT, "-");
            // 已结束任务数 +1
            patrolPlanService.updateTaskCount(e.getPlanId(), BusinessConstants.TASK_DONE_COUNT, "+");
        });
        return success(Boolean.TRUE.toString());
    }

}
